﻿using System;
using System.Text;
using System.Windows.Forms;
using SdmxMl.Manager;
using SdmxMl.Common;
using SdmxMl.Structure;
using Telerik.WinControls;
using Telerik.WinControls.Data;
using Telerik.WinControls.UI;
using Telerik.WinControls.UI.Export;
using SdmxDiff;


namespace ChopPlugin
{
    /// <summary>User control for Plug-in CHOP </summary>
    public partial class UcChop : UserControl, PluginInterface.IPlugin
    {
        #region Constants

        public const string ERR_CAPTION = "Error";
        public const string EXPORT_CAPTION = "Export";
        const string ERR_OCCURED = "An error occured. Reason: ";
        const string PDF_FILTER = "PDF files (*.pdf)|*.pdf|All files (*.*)|*.*";
        public const string EXCEL_FILTER = "Excel (*.xls)|*.xls";
        public const string MSG_EXPORT_SUCCESS = "The data was exported successfully. Do you want to open the file?";
        const string MSG_SEL_PREV_CHOP = "Please select previous version of CHOP!";
        const string MSG_MODIFIED_CL = "Modified codelists are:";
        #endregion

        #region Internal Members

        /// <summary>SDMX artefact holding CHOP</summary>
        private HierarchicalCodelistType hclChop;
        /// <summary>Grid helper manager</summary>
        private ExportGridCreator gridCreator;

        #endregion

        #region Construction

        public UcChop()
        {
            InitializeComponent();

            gridCreator = new ExportGridCreator(radGridView);
            radMenuExport.Enabled = false;
            radMenuItemPdf.Enabled = false;
            radMenuItemDiff.Enabled = false;
            radMenuItemApplyModif.Enabled = false;
            radMenuItemCreateChop.Enabled = true;
        }
        #endregion

        #region IPlugin Members

        /// <summary>Event is part of interface but not used </summary>
        public event PluginInterface.PluginEvent PluginEventExposed
        {
            add { }
            remove { }
        }


        public void Init(System.Xml.XmlDocument xDoc, object obExtend)
        {
        }

        public UserControl VisualComponent()
        {
            return this;
        }

        public bool RequiresInit
        {
            get { return false; }
        }

        #endregion

        #region Pdf Generation Event

        private void radMenuItemPdf_Click(object sender, EventArgs e)
        {
            DlgPdfOptions aDlg = new DlgPdfOptions();
            aDlg.ShowDialog();
            if (aDlg.DialogResult == DialogResult.OK)
            {
                try
                {
                    SaveFileDialog sfd = new SaveFileDialog();
                    sfd.DefaultExt = ".pdf";
                    sfd.Filter = PDF_FILTER;
                    if (hclChop != null && sfd.ShowDialog() == DialogResult.OK)
                    {
                        this.Refresh();
                        using (new SdmxMl.Helper.CWaitCursor())
                        {
                            PdfChop pdf = new PdfChop();
                            pdf.Generate(hclChop, sfd.FileName, aDlg.Options);

                            DialogResult dr = RadMessageBox.Show(MSG_EXPORT_SUCCESS,
                                EXPORT_CAPTION, MessageBoxButtons.YesNo, RadMessageIcon.Question);
                            if (dr == DialogResult.Yes)
                            {
                                System.Diagnostics.Process.Start(sfd.FileName);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ERR_OCCURED + ex.Message,
                        ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        #endregion

        #region Artefact diff

        private void radMenuItemDiff_Click(object sender, EventArgs e)
        {
            // If CSV grid generated


        }
        #endregion

        #region Multilang Grid filling Event

        private void radMenuItemGenExcel_Click(object sender, EventArgs e)
        {
            try
            {
                if (hclChop != null)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        radMenuItemHideTopLevel.IsChecked = false;
                        gridCreator.LoadGridData(hclChop, radMenuItemFilter.IsChecked);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERR_OCCURED + ex.Message,
                    ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region User control Load event

        private void UcChop_Load(object sender, EventArgs e)
        {

            // CHOP Agency id in new registry is CH1, alias generated differently
            if (SdmxMl.Multiplexor.Mux.IsNewSmsRegistry)
            {
                ChopCodes.CHOP_AGENCY_ID = "CH1";
                ChopCodes.ALIAS_BASE = "INCL_CL_";
            }
        }
        #endregion

        #region Excel export

        /// <summary>Excel Export Event</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void radMenuItemExportExcel_Click(object sender, EventArgs e)
        {
            RunExportToExcelML();
        }

        /// <summary> Export Grid to Excel </summary>
        private void RunExportToExcelML()
        {
            ExportToExcelML excelExporter = null;
            try
            {
                excelExporter = new ExportToExcelML(this.radGridView);
                //   excelExporter.ExcelCellFormatting += new Telerik.WinControls.UI.Export.ExcelML.ExcelCellFormattingEventHandler(exporter_ExcelCellFormatting);
                excelExporter.SummariesExportOption = SummariesOption.ExportAll;
                //set export settings
                excelExporter.ExportVisualSettings = false;
                excelExporter.ExportHierarchy = true;
                excelExporter.HiddenColumnOption = HiddenOption.DoNotExport;

                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = EXCEL_FILTER;
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        excelExporter.RunExport(saveFileDialog.FileName);

                        DialogResult dr = RadMessageBox.Show(MSG_EXPORT_SUCCESS,
                            EXPORT_CAPTION, MessageBoxButtons.YesNo, RadMessageIcon.Question);
                        if (dr == DialogResult.Yes)
                        {
                            System.Diagnostics.Process.Start(saveFileDialog.FileName);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                RadMessageBox.SetThemeName(this.radGridView.ThemeName);
                RadMessageBox.Show(this, ex.Message, ERR_CAPTION, MessageBoxButtons.OK, RadMessageIcon.Error);
            }
        }


        #endregion

        #region Option Events

        private void radMenuItemFilter_Click(object sender, EventArgs e)
        {
            RadMenuItem menuItem = sender as RadMenuItem;
            if (menuItem != null)
                radGridView.EnableFiltering = menuItem.IsChecked;
            if (radGridView.EnableFiltering == false)
            {
                if (radGridView.Columns.Contains("Level"))
                    radGridView.Columns["Level"].FilterDescriptor = null;
                radMenuItemHideTopLevel.IsChecked = false;

            }
        }

        private void radMenuItemExpandGroup_Click(object sender, EventArgs e)
        {
            RadMenuItem menuItem = sender as RadMenuItem;
            if (menuItem != null)
                radGridView.MasterTemplate.AutoExpandGroups = menuItem.IsChecked;
        }

        private void radMenuItemHideTopLevel_Click(object sender, EventArgs e)
        {
            GridViewTextBoxColumn levelColumn = null;

            // determine level column
            foreach (GridViewColumn gc in this.radGridView.Columns)
            {
                if (gc.Name.ToLower().Contains("level"))
                {
                    levelColumn = gc as GridViewTextBoxColumn;
                    break;
                }
            }
            if (levelColumn == null)
                return;

            if (radMenuItemHideTopLevel.IsChecked == false)
                levelColumn.FilterDescriptor = null;
            else
            {
                // activate filter if not
                if (radMenuItemFilter.IsChecked == false)
                {
                    radMenuItemFilter.IsChecked = true;
                    radMenuItemFilter_Click(radMenuItemFilter, EventArgs.Empty);
                }
                // set filter for column level to
                FilterDescriptor filter1 = new FilterDescriptor();
                filter1.Operator = FilterOperator.IsNotEqualTo;
                filter1.Value = "1";
                filter1.IsFilterEditor = true;
                levelColumn.FilterDescriptor = filter1;
            }
        }



        #endregion

        #region Select CHOP artefact

        /// <summary>From main tree current selection, request to work with</summary>
        /// <param name="sender"></param><param name="e"></param>
        private void radMenuItemInfoSelected_Click(object sender, EventArgs e)
        {
            TreeView tv = ReferenceManager.TreeSdmx;
            if (tv == null)
                return;
            try
            {

                DlgVersions aDlg = new DlgVersions();
                aDlg.BindVersionsOf(UrnManager.FullIdToUrn(SdmxArtefactType.HierarchicalCodelists,
                    ChopCodes.CHOP_AGENCY_ID + "+" + ChopCodes.HIERARCHICAL_CODELIST_ID + "+1.0"));
                if (aDlg.ShowDialog(this) == DialogResult.OK)
                {

                    // If already in memory, navigate otherwhile get from registry
                    UrnParser p = new UrnParser(aDlg.SelectedVersionUrn);
                    if (p.IsSupported)
                    {
                        // If already in memory, navigate otherwhile get from regidtry
                        if (NavigationManager.LocatenavigateProject(p.ArType, p.FullIdent, p) == null)
                            NavigationManager.NavigateWithRegistry(p.ArType, p.FullIdent, true, p);

                    }
                }

                if (tv.SelectedNode != null)
                {
                    HierarchicalCodelistType hcl = tv.SelectedNode.Tag as HierarchicalCodelistType;
                    if (hcl != null && hcl.AgencyId == ChopCodes.CHOP_AGENCY_ID && hcl.Id == ChopCodes.HIERARCHICAL_CODELIST_ID)
                    {
                        hclChop = hcl;
                        radGridView.MasterTemplate.Rows.Clear();

                        radMenuItemSelectChop.Text = "CHOP Selected: " + hclChop.FullIdent + " - " + hclChop.Name.ToString();
                        radMenuExport.Enabled = true;
                        radMenuItemPdf.Enabled = true;
                        radMenuItemApplyModif.Enabled = true;
                        radMenuItemDiff.Enabled = true;
                        radMenuItemOptions.Enabled = true;
                        radMenuItemCreateChop.Enabled = false;
                    }
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Create CHOP SDMX Hierarchy form Excel document

        /// <summary>
        /// Create CHOP SDMX Hierarchy form Excel document
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void radMenuItemCreateChop_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog of = new OpenFileDialog();
                of.Filter = EXCEL_FILTER;
                if (of.ShowDialog() == DialogResult.OK)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        // check not already in tree

                        // Create
                        ChopCodes generator = new ChopCodes(of.FileName);
                        SmManager sm = generator.ConstructCodes();

                        // Add in tree 
                        TreeSdmxManager treeMgr = ReferenceManager.TreeMgr;

                        if (treeMgr != null)
                        {
                            object ob = NavigationManager.LoadFromSmManager(sm);
                            NavigationManager.RequestNavigation(ob);
                        }
                    }
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region CSV generation

        private void radMenuItemGenCsv_Click(object sender, EventArgs e)
        {
            try
            {
                if (hclChop != null)
                {
                    // Select previous CHOP Version
                    DlgVersions aDlg = new DlgVersions();
                    aDlg.BindVersionsOf(UrnManager.FullIdToUrn(SdmxArtefactType.HierarchicalCodelists,
                         ChopCodes.CHOP_AGENCY_ID + "+" + ChopCodes.HIERARCHICAL_CODELIST_ID + "+1.0"));
                    if (aDlg.ShowDialog(this) == DialogResult.OK)
                    {

                        // If already in memory, navigate otherwhile get from registry
                        UrnParser p = new UrnParser(aDlg.SelectedVersionUrn);
                        if (p.IsSupported)
                        {
                            // If already in memory, navigate otherwhile get from regidtry
                            if (NavigationManager.LocatenavigateProject(p.ArType, p.FullIdent, p) == null)
                                NavigationManager.NavigateWithRegistry(p.ArType, p.FullIdent, true, p);
                        }

                        HierarchicalCodelistType hclPrevious = null;
                        if (ReferenceManager.TreeSdmx.SelectedNode != null)
                            hclPrevious = ReferenceManager.TreeSdmx.SelectedNode.Tag as HierarchicalCodelistType;
                        if (hclPrevious == null)
                            throw new ApplicationException(MSG_SEL_PREV_CHOP);

                        using (new SdmxMl.Helper.CWaitCursor())
                        {
                            radMenuItemHideTopLevel.IsChecked = false;
                            gridCreator.LoadGridCsvReport(hclChop, hclPrevious, radMenuItemFilter.IsChecked);
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ERR_OCCURED + ex.Message,
                    ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        #endregion

        #region Event Check Refered code existance

        private void radMenuItemCheckDiff_Click(object sender, EventArgs e)
        {
            try
            {
                using (new SdmxMl.Helper.CWaitCursor())
                {
                    if (hclChop != null)
                    {
                        gridCreator.CheckreferedCodes(hclChop);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERR_OCCURED + ex.Message,
                    ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        #endregion

        private void radMenuItemGenDiffReport_Click(object sender, EventArgs e)
        {
            try
            {
                //         ShisHierarchy sh = new ShisHierarchy(@"C:\Doc\CRIME\CL_630.xls");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERR_OCCURED + ex.Message,
                    ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        #region Code Navigation

        private void radGridView_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                gridCreator.NavigateToCode(sender as GridDataCellElement);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERR_OCCURED + ex.Message,
                    ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Modification list

        /// <summary>
        /// Apply modification list provided in Excel 2003
        /// </summary>
        /// <param name="sender"></param><param name="e"></param>
        private void radMenuItemApplyModif_Click(object sender, EventArgs e)
        {
            if (hclChop != null)
            {
                OpenFileDialog of = new OpenFileDialog();
                of.Filter = EXCEL_FILTER;
                if (of.ShowDialog() == DialogResult.OK)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        try
                        {
                            ModificationList modifList = new ModificationList(of.FileName);

                            // Check modifs can be done
                            modifList.Apply(hclChop, false);

                            // apply modif
                            modifList.Apply(hclChop, true);

                            // Inform about modifid codelists
                            StringBuilder sb = new StringBuilder(EXCEL_FILTER + Environment.NewLine);
                            foreach (CodeListType clt in modifList.ModifiedCodelists)
                                sb.Append(clt.FullIdent).Append(Environment.NewLine);
                            MessageBox.Show(this, sb.ToString(), "Applied modifications", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ERR_OCCURED + ex.Message,
                                ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
            }
        }
        #endregion

        #region Import Changes for new version
        private void radMenuItemNewVersion_Click(object sender, EventArgs e)
        {
            if (hclChop == null)
            {
                MessageBox.Show("Please select CHOP source version first!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // Ask new version number
            DlgNewVersion aDlg = new DlgNewVersion();
            if (aDlg.ShowDialog() == DialogResult.OK)
            {

                // Fetch new version mutation file
                OpenFileDialog of = new OpenFileDialog();
                of.Filter = EXCEL_FILTER;
                if (of.ShowDialog() == DialogResult.OK)
                {
                    using (new SdmxMl.Helper.CWaitCursor())
                    {
                        try
                        {
                            // Clone actual
                            SdmxMl.Helper.HierarchicalCloner hierarchyCloner = new SdmxMl.Helper.HierarchicalCloner(null);
                            HierarchicalCodelistType hclChopCloned = hierarchyCloner.Clone(new ArtefactRefBase(hclChop.FullIdent), aDlg.Version);

                            // process mutations
                            ModificationVersionList mutator = new ModificationVersionList(of.FileName);
                            mutator.Apply(hierarchyCloner.Cache, hclChopCloned);

                            // display new version in Main tree
                            NavigationManager.LoadFromSmManager(hierarchyCloner.Cache);


                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ERR_OCCURED + ex.Message,
                                ERR_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
            }



        }

        #endregion
    }
}
